/*
 *    Copyright (c) 2018-2025, proj All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the proj developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: proj
 */

package com.ykht.proj.coupon.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ykht.proj.activity.api.feign.RemoteDiscountPlanService;
import com.ykht.proj.activity.api.feign.RemoteDiscountPlanShopService;
import com.ykht.proj.activity.api.feign.RemoteOrderCardShopService;
import com.ykht.proj.activity.vo.CardShopDto;
import com.ykht.proj.activity.vo.CnDiscountShopVoReq;
import com.ykht.proj.activity.vo.CnGroupShopVoReq;
import com.ykht.proj.admin.api.feign.RemoteUserService;
import com.ykht.proj.admin.api.vo.UserVO;
import com.ykht.proj.common.core.util.R;
import com.ykht.proj.common.log.annotation.SysLog;
import com.ykht.proj.common.security.annotation.Inner;
import com.ykht.proj.common.security.util.SecurityUtils;
import com.ykht.proj.coupon.Enum.DelFlagEnum;
import com.ykht.proj.coupon.Enum.DisplayEnum;
import com.ykht.proj.coupon.Enum.StatusEnum;
import com.ykht.proj.coupon.Enum.UserTypeEnum;
import com.ykht.proj.coupon.entity.CnBrand;
import com.ykht.proj.coupon.entity.CnShop;
import com.ykht.proj.coupon.service.CnBrandService;
import com.ykht.proj.coupon.service.CnCompanyService;
import com.ykht.proj.coupon.service.CnShopService;
import com.ykht.proj.coupon.utils.LocationUtile;
import com.ykht.proj.coupon.vo.CnShopVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 店铺表
 *
 * @author proj code generator
 * @date 2020-11-18 17:10:45
 */
@RestController
@AllArgsConstructor
@RequestMapping("/cnshop")
@Api(value = "cnshop", tags = "店铺表管理")
@Slf4j
public class CnShopController {

	private final CnShopService cnShopService;

	private final CnCompanyService cnCompanyService;

	private final CnBrandService cnBrandService;
	private final RemoteUserService remoteUserService;
	/**
	 * 优惠方案和门店关联表 服务
	 */
	private final RemoteDiscountPlanShopService remoteDiscountPlanShopService;
	/**
	 * 优惠方案 服务
	 */
	private final RemoteDiscountPlanService remoteDiscountPlanService;
	/**
	 * 优惠方案 服务
	 */
	private final RemoteOrderCardShopService remoteOrderCardShopService;

	/**
	 * 根据角色类型 获取后台的门店列表 分页查询
	 *
	 * @param page     分页对象
	 * @param cnShopVo 店铺表
	 * @return
	 */
	@ApiOperation(value = "分页查询", notes = "分页查询")
	@GetMapping("/page")
	@PreAuthorize("@pms.hasPermission('coupon_cnshop_view')")
	public R getCnShopPage(Page page, CnShopVo cnShopVo) {
		log.info("->根据角色类型 获取后台的门店列表 分页查询:{}", JSONUtil.toJsonStr(cnShopVo));
		return cnShopService.findPage(page, cnShopVo);
	}

	@ApiOperation(value = "根据品牌id和门店名查询", notes = "根据品牌id和门店名查询")
	@PostMapping("/getByBrand")
//	@PreAuthorize("@pms.hasPermission('coupon_cnbrand_view')" )
	public R getByBrand(@RequestBody CnShopVo cnShopVo) {
		Map<String, Object> map = new HashMap<>();
		map.put("delFlag", 0);
		if (null != cnShopVo) {
			if (null != cnShopVo.getBrandId()) {
				map.put("brandId", cnShopVo.getBrandId());
			}
			if (null != cnShopVo.getName()) {
				map.put("name", cnShopVo.getName());
			}
		}
		List<CnShop> list = cnShopService.listByVoMap(map);
		return R.ok(list);
	}

	@ApiOperation(value = "根据公司id查询门店列表")
	@GetMapping("/getShopListByCompanyId")
	public R getShopListByCompanyId(Long companyId) {
		List<CnShop> list = cnShopService.list(Wrappers.lambdaQuery(CnShop.class).eq(CnShop::getCompanyId, companyId));
		return R.ok(list);
	}


	/**
	 * 通过id查询店铺表
	 *
	 * @param id id
	 * @return R
	 */
	@ApiOperation(value = "通过id查询", notes = "通过id查询")
	@GetMapping("/{id}")
	@PreAuthorize("@pms.hasPermission('coupon_cnshop_view')")
	public R getById(@PathVariable("id") Long id) {
		return R.ok(cnShopService.getById(id));
	}

	@ApiOperation(value = "通过id查询基本资料", notes = "通过id查询基本资料")
	@PostMapping("getDetailById")
	@PreAuthorize("@pms.hasPermission('coupon_cnshop_view')")
	public R getDetailById(@RequestBody CnShopVo vo) {
		CnShopVo shopVo = cnShopService.getDetailById(vo.getId());
		UserVO userVO = remoteUserService.getByIdUser(shopVo.getLoginId());
		if (userVO != null) {
			shopVo.setUsername(userVO.getUsername());
			shopVo.setUserId(userVO.getUserId());
		}
		return R.ok(shopVo);
	}

	/**
	 * 新增店铺表
	 *
	 * @param cnShopVo 店铺表
	 * @return R
	 */
	@ApiOperation(value = "新增店铺表", notes = "新增店铺表")
	@SysLog("新增店铺表")
	@PostMapping
//	@PreAuthorize("@pms.hasPermission('coupon_cnshop_add')")
	public R save(@RequestBody CnShopVo cnShopVo) throws Exception {
		log.info("->新增店铺表:{}", JSONUtil.toJsonStr(cnShopVo));
		if (!StringUtils.isNotBlank(cnShopVo.getLongitude()) || !StringUtils.isNotBlank(cnShopVo.getLatitude())) {
			return R.failed("请输入正确地址");
		}
		String coordinate = LocationUtile.getCoordinate(cnShopVo.getLongitude(), cnShopVo.getLatitude());
		cnShopVo.setTradeArea(getBusiness(coordinate));
		CnBrand cnBrand = new CnBrand().selectById(cnShopVo.getBrandId());
		cnShopVo.setCompanyId(cnBrand.getCompanyId());
		return cnShopService.saveAndUser(cnShopVo);
	}

	/**
	 * 修改店铺表
	 *
	 * @param cnShopVo 店铺表
	 * @return R
	 */
	@ApiOperation(value = "修改店铺表", notes = "修改店铺表")
	@SysLog("修改店铺表")
	@PutMapping
//	@PreAuthorize("@pms.hasPermission('coupon_cnshop_edit')")
	public R updateById(@RequestBody CnShopVo cnShopVo) throws Exception {
		log.info("->修改店铺表:{}", JSONUtil.toJsonStr(cnShopVo));
		if (!StringUtils.isNotBlank(cnShopVo.getLongitude()) || !StringUtils.isNotBlank(cnShopVo.getLatitude())) {
			return R.failed("请输入正确地址");
		}
		String coordinate = LocationUtile.getCoordinate(cnShopVo.getLongitude(), cnShopVo.getLatitude());
		cnShopVo.setTradeArea(getBusiness(coordinate));
		return cnShopService.updateAndUser(cnShopVo);
	}

	@ApiOperation(value = "根据地址获取经纬度", notes = "根据地址获取经纬度")
	@GetMapping("geo")
	@Inner(false)
	public R v3GeocodeGeo(@RequestParam String address) {
		try {
			String data = LocationUtile.geo(address);
			JSONObject jsonObject = JSONUtil.parseObj(data);
			String status = jsonObject.getStr("status");
			if (!"1".equals(status)) return R.failed("请输入正确的店铺地址！");

			cn.hutool.json.JSONArray geocodes = JSONUtil.parseArray(jsonObject.getStr("geocodes"));
			Object locationObj = geocodes.get(0);
			JSONObject locationJson = JSONUtil.parseObj(locationObj);
			String location = locationJson.getStr("location");
			/*String[] array= location.split(",");
			String longitude = array[0];
			String latitude = array[1];*/
			return R.ok(location);
		} catch (Exception e) {
			e.printStackTrace();
			return R.failed("请输入正确的店铺地址！");
		}
	}


	/**
	 * 通过id删除店铺表
	 *
	 * @param id id
	 * @return R
	 */
	@ApiOperation(value = "通过id删除店铺表", notes = "通过id删除店铺表")
	@SysLog("通过id删除店铺表")
	@DeleteMapping("/{id}")
	@PreAuthorize("@pms.hasPermission('coupon_cnshop_del')")
	public R removeById(@PathVariable Long id) {
		return R.ok(cnShopService.removeById(id));
	}

	/**
	 * 上传
	 *
	 * @param file
	 * @return
	 */
	@ApiOperation(value = "上传文件")
	@PostMapping("uploadFile")
	public R uploadFile(@RequestParam("file") MultipartFile file) {
		return R.ok(cnBrandService.uploadFile(file));
	}

	/**
	 * 是否展示
	 *
	 * @param id
	 * @return
	 */
	@ApiOperation(value = "是否展示")
	@GetMapping("exhibition")
	public R exhibition(Long id) {
		CnShop cnShop = cnShopService.getById(id);
		UpdateWrapper<CnShop> updateWrapper = new UpdateWrapper<>();
		if (cnShop.getDisplay().equals(StatusEnum.normal.getValue())) {
			updateWrapper.lambda().set(CnShop::getDisplay, StatusEnum.forbid.getValue());
		} else {
			updateWrapper.lambda().set(CnShop::getDisplay, StatusEnum.normal.getValue());
		}
		updateWrapper.lambda().eq(CnShop::getId, id);
		return R.ok(cnShopService.update(updateWrapper));
	}

	/**
	 * 获取品牌
	 */
	@ApiOperation(value = "获取品牌")
	@GetMapping("getBrand")
	public R getBrand() {
		List<CnBrand> list = cnBrandService.list(Wrappers.lambdaQuery(CnBrand.class)
				.eq(CnBrand::getLoginId, SecurityUtils.getUserId()));
		return R.ok(list);
	}

	@ApiOperation(value = "创建门店时候获取品牌列表")
	@GetMapping("/getBrand_v2")
	public R getBrand_v2() {
		List list = ListUtil.empty();
		if (SecurityUtils.getUser().getUserType() == UserTypeEnum.brand.getValue()) {
			list = cnBrandService.list(Wrappers.lambdaQuery(CnBrand.class)
					.eq(CnBrand::getLoginId, SecurityUtils.getUserId()).eq(CnBrand::getDisplay, 0));
		} else if (SecurityUtils.getUser().getUserType() == UserTypeEnum.company.getValue()) {
			list = cnBrandService.list(Wrappers.lambdaQuery(CnBrand.class)
					.eq(CnBrand::getCompanyId, SecurityUtils.getSjId()).eq(CnBrand::getDisplay, 0));
		}
		return R.ok(list);
	}

	@ApiOperation(value = "获取所以品牌")
	@GetMapping("/getBrandAll")
	public R getBrandAll() {
		CnBrand cnBrand = new CnBrand();
		cnBrand.setDisplay(0);
		if (SecurityUtils.getUser().getUserType() == UserTypeEnum.admin.getValue()) {

		} else if (SecurityUtils.getUser().getUserType() == UserTypeEnum.company.getValue()) {
			cnBrand.setCompanyId(SecurityUtils.getSjId());
		}
		return R.ok(cnBrandService.list(Wrappers.query(cnBrand)));
	}


	private String getAddress(String coordinate) {
		String str = JSON.parseObject(coordinate).getString("regeocodes");
		String[] strr = str.split("\"formatted_address\":\"");
		String[] strrr = strr[1].split("\",\"addressComponent\":");
		return strrr[0];
	}

	private String getBusiness(String coordinate) {
		String str = JSON.parseObject(coordinate).getString("regeocodes");
		JSONArray objects = JSON.parseArray(str);
		com.alibaba.fastjson.JSONObject jsonObject = objects.getJSONObject(0);
		String businessAreas = jsonObject.getString("addressComponent");
		String[] split = businessAreas.split("\"name\":\"");
		if (split == null || split.length < 2) {
			return null;
		}
		String[] split1 = split[1].split("\",\"location\":");
		return split1[0];
	}

	private R analysis(CnShopVo cnShopVo) {
		try {
			if (StringUtils.isNotBlank(cnShopVo.getLongitude()) && StringUtils.isNotBlank(cnShopVo.getLatitude())) {
			/*JSONObject map= cnShopVo.getMap();
			JSONObject addressComponent = map.getJSONObject("addressComponent");
			if(addressComponent==null){
				JSONObject location = map.getJSONObject("location");
				cnShopVo.setLongitude(location.getStr("lng"));
				cnShopVo.setLatitude(location.getStr("lat"));
			}else {
				cnShopVo.setLongitude(map.getStr("longitude"));
				cnShopVo.setLatitude(map.getStr("latitude"));
			}*/
				String coordinate = LocationUtile.getCoordinate(cnShopVo.getLongitude(), cnShopVo.getLatitude());
				cnShopVo.setTradeArea(getBusiness(coordinate));
				CnShop cnShop = BeanUtil.toBean(cnShopVo, CnShop.class);
				if (cnShop.getId() != null) {
					return R.ok(cnShopService.updateById(cnShop));
				} else {
					return R.ok(cnShopService.save(cnShop));
				}
			} else {
				return R.failed("请输入正确地址");
			}
		} catch (Exception e) {
			e.printStackTrace();
			return R.failed();
		}
	}

	@ApiOperation(value = "根据登录人角色和品牌ID获取门店", notes = "根据登录人角色和品牌ID获取门店")
	@GetMapping("/getShop")
	public R getShop(Long brandId) {
		QueryWrapper<CnShop> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda().eq(CnShop::getDelFlag, 0).eq(CnShop::getBrandId, brandId);
		return R.ok(cnShopService.list(queryWrapper));
	}


	/**
	 * 门店上下架
	 *
	 * @param cnShopVo 门店表
	 * @return R
	 */
	@ApiOperation(value = "门店上下架", notes = "门店上下架")
	@SysLog("门店上下架")
	@PostMapping("/updateByDisplay")
	public R updateByDisplay(@RequestBody CnShopVo cnShopVo) throws Exception {
		log.info("->门店上下架:{}", JSONUtil.toJsonStr(cnShopVo));
		return cnShopService.updateByDisplay(cnShopVo);
	}


	@ApiOperation(value = "创建优惠方案获取门店列表（根据品牌id, 门店名, 地址查询)", notes = "创建优惠方案获取门店列表（根据品牌id, 门店名, 地址查询)")
	@GetMapping("/getByDiscountPlan")
	public R<IPage<CnDiscountShopVoReq>> getByDiscountPlan(Page page, CnDiscountShopVoReq cnDiscountShopVoReq) {
		log.info("->创建优惠方案获取门店列表（根据品牌id, 门店名, 地址查询):{}", cnDiscountShopVoReq);
		IPage<CnDiscountShopVoReq> iPage = cnShopService.getByDiscountPlan(page, cnDiscountShopVoReq);
		if (null == iPage.getRecords() || iPage.getRecords().size() == 0) {
			return R.ok(iPage);
		}
		iPage.getRecords().stream().forEach(itme -> {
			itme.setUseType(0);
		});
		log.info("->获取已有优惠方案门店列表和他们的状态");
		R<List<CnDiscountShopVoReq>> listR = remoteDiscountPlanShopService.getByDiscountPlanShop(cnDiscountShopVoReq);
		List<CnDiscountShopVoReq> cnDiscountShopVoReqList = listR.getData();
		if (null == cnDiscountShopVoReqList || cnDiscountShopVoReqList.size() == 0) {
			return R.ok(iPage);
		}
		iPage.getRecords().stream().forEach(itme -> {
			cnDiscountShopVoReqList.stream().forEach(cnShopVoReq1 -> {
				if (itme.getId().equals(cnShopVoReq1.getId())) {
					itme.setUseType(0);
					if (cnShopVoReq1.getUseTypeShow().contains("1")) {
						itme.setUseType(1);
					}
				}
			});
		});
		return R.ok(iPage);
	}


	@ApiOperation(value = "创建群组取门店列表（根据品牌标签, 品牌/门店名, 地址查询,协议类型)", notes = "创建群组取门店列表（根据品牌标签, 品牌/门店名, 地址查询,协议类型)")
	@GetMapping("/getByGroup")
	public R<Page<CnGroupShopVoReq>> getByGroup(Page page, CnGroupShopVoReq cnGroupShopVoReq) {
		log.info("->创建群组取门店列表（根据品牌标签, 品牌/门店名, 地址查询,协议类型):{}", cnGroupShopVoReq);
		List<CnGroupShopVoReq> reqIPage = cnShopService.getByGroup(cnGroupShopVoReq);
		if (null == reqIPage || reqIPage.size() == 0) {
			Page<CnGroupShopVoReq> reqPage = new Page();
			return R.ok(reqPage);
		}
		cnGroupShopVoReq.setPage(page);
		List<Long> shopIdList = reqIPage.stream().map(CnGroupShopVoReq::getId).collect(Collectors.toList());
		cnGroupShopVoReq.setShopIdList(shopIdList);
		log.info("->获取已有优惠方案门店列表");
		R<Page<CnGroupShopVoReq>> byGroupShop = remoteDiscountPlanService.getByGroupShop(cnGroupShopVoReq);
		List<CnGroupShopVoReq> reqList = byGroupShop.getData().getRecords();
		if (null != cnGroupShopVoReq.getPlanType()) {
			if (null == reqList || reqList.size() == 0) {
				return byGroupShop;
			} else {
				reqList.stream().forEach(itme -> {
					reqIPage.stream().forEach(lst -> {
						if (itme.getId().equals(lst.getId())) {
							itme.setName(lst.getName());
							itme.setBrandId(lst.getBrandId());
							itme.setBrandName(lst.getBrandName());
							itme.setLabelName(lst.getLabelName());
							itme.setProvinceName(lst.getProvinceName());
							itme.setCityName(lst.getCityName());
							itme.setAreaName(lst.getAreaName());
//							itme.setAgreementStatus(lst.getAgreementStatus());
							itme.setAddress(lst.getAddress());
						}
					});
				});
				return byGroupShop;
			}
		} else {
			if (null == reqList || reqList.size() == 0) {
				return byGroupShop;
			} else {
				reqList.stream().forEach(itme -> {
					reqIPage.stream().forEach(lst -> {
						if (itme.getId().equals(lst.getId())) {
						/*	itme.setPlanType(lst.getPlanType());
							itme.setDiscount(lst.getDiscount());
							itme.setLowMoney(lst.getLowMoney());
							itme.setPlanStaTime(lst.getPlanStaTime());
							itme.setPlanEndTime(lst.getPlanEndTime());
							itme.setUsageTimes(lst.getUsageTimes());
							itme.setApplyShopType(lst.getApplyShopType());
							itme.setAgreementStatus(lst.getAgreementStatus());*/

							itme.setName(lst.getName());
							itme.setBrandId(lst.getBrandId());
							itme.setBrandName(lst.getBrandName());
							itme.setLabelName(lst.getLabelName());
							itme.setProvinceName(lst.getProvinceName());
							itme.setCityName(lst.getCityName());
							itme.setAreaName(lst.getAreaName());
//							itme.setAgreementStatus(lst.getAgreementStatus());
							itme.setAddress(lst.getAddress());
						}
					});
				});
			}
		}
		return byGroupShop;
	}


	@ApiOperation(value = "PC 获取会员能使用门店列表 分页", notes = "PC 获取会员能使用门店列表 分页")
	@GetMapping("/getByInfoShopListPage")
	public R<Page<CardShopDto>> getByInfoShopListPage(Page page, CardShopDto cardShopDto) {
		log.info("->PC 获取会员卡能使用门店列表 分页:{}{}", page, cardShopDto);
		List<CardShopDto> list = cnShopService.getByInfoShop(cardShopDto);
		if (null == list || list.size() == 0) {
			return R.ok(null);
		}
		List<Long> shopIdList = list.stream().map(CardShopDto::getShopId).collect(Collectors.toList());
		cardShopDto.setShopIdList(shopIdList);
		log.info("->获取已有优惠方案门店列表");
		cardShopDto.setPage(page);
		R<Page<CardShopDto>> byInfoShopPage = remoteOrderCardShopService.getByInfoShopPage(cardShopDto);
		if (null == byInfoShopPage.getData() || byInfoShopPage.getData().getRecords().size() == 0){
			return R.ok();
		}
		List<CardShopDto> reqList = byInfoShopPage.getData().getRecords();
		reqList.stream().forEach(itme -> {
			list.stream().forEach(shop ->{
				if (itme.getShopId().equals(shop.getShopId())){
					itme.setShopName(shop.getShopName());
					itme.setBrandName(shop.getBrandName());
					itme.setLabelName(shop.getLabelName());
					itme.setProvinceName(shop.getProvinceName());
					itme.setCityName(shop.getCityName());
					itme.setAreaName(shop.getAreaName());
					itme.setAreaName(shop.getAreaName());
					itme.setAddress(shop.getAddress());
					itme.setLabelNameShow(shop.getLabelNameShow());
				}
			});
		});
		return byInfoShopPage;
	}

}
